package org.thss.petri.gef.editparts;

import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.thss.petri.gef.editparts.policies.NodeLayoutEditPolicy;
import org.thss.petri.gef.editparts.policies.PetriNetFireEditPolicy;
import org.thss.petri.model.PetriNet;


public class PetriNetEditPart extends AbstractGraphicalEditPart  implements Adapter {

	private PetriNet model;
	
	public PetriNetEditPart(PetriNet model) {
		this.model = model;
		setModel(model);
	}
	
	@Override
	protected EList getModelChildren() {
		return ((PetriNet) getModel()).getNodes();
	}
	
	@Override
	protected IFigure createFigure() {
        Figure figure = new Figure();
        figure.setLayoutManager(new XYLayout());
        return figure;
	}

	@Override
	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.LAYOUT_ROLE, new NodeLayoutEditPolicy());
		installEditPolicy(EditPolicy.NODE_ROLE,new PetriNetFireEditPolicy());
	}
	
	/**
	 * be an adapter
	 */
	@Override
	public void activate() {
		if (isActive()) {
			return;
		}
		super.activate();
		((Notifier) getModel()).eAdapters().add(this);
	}
	
	@Override
	public void deactivate() {
		if (!isActive()) {
			return;
		}
		super.deactivate();
		((Notifier) getModel()).eAdapters().remove(this);
	}
	
	/**
	 * Listen to model change from here
	 */

	@Override
	public void notifyChanged(Notification notification) {
		int type = notification.getEventType();
		switch(type) {
		case Notification.ADD:
		case Notification.ADD_MANY:
		case Notification.REMOVE:
		case Notification.REMOVE_MANY:
			refreshChildren();
			break;
		case Notification.SET:
			refreshVisuals();
			break;
		}
	}
	
	@Override
	public Notifier getTarget() {
		return model;
	}

	@Override
	public void setTarget(Notifier newTarget) {
		if (newTarget == null) {
			return;
		}
		model = (PetriNet) newTarget;
		setModel(model);
	}

	@Override
	public boolean isAdapterForType(Object type) {
		return type.equals(getModel().getClass());
	}
	
}
